package com.nifostasky.main.thread.ThreadScheduling;

/**
 * Java的调度算法
 */
public class CpuScheduling {
    public static void main(String[] args) throws InterruptedException {

        System.out.println("================================================================================================");

        Runnable runnable = () -> {
            for (int i = 0; i < 100; i++) {
//                try {
//                    Thread.sleep(10);
//                } catch (InterruptedException e) {
//                    e.printStackTrace();
//                }
                if (i == 99){
                    System.out.println(Thread.currentThread().getName() + "::::: " + i);
                }
                System.out.println(Thread.currentThread().getName() + ": " + i);
            }
        };

        //次要线程1,2,3
        Thread thread1 = new Thread(runnable);
        Thread thread2 = new Thread(runnable);
        Thread thread3 = new Thread(runnable);

        //设置线程名
        thread1.setName("thread1");
        thread2.setName("thread2");
        thread3.setName("thread3");


        //设置优先级 值越大优先级越高
        thread1.setPriority(1);
        thread2.setPriority(5);
        thread3.setPriority(10);

        //主线程
        thread1.start();
        thread2.start();
        thread3.start();
        Thread mainThread = Thread.currentThread();


        thread1.join();
        thread2.join();
        thread3.join();
        //获取优先级
        System.out.println("获取优先级:======================================");
        System.out.println(thread1.getName()+ ": " + thread3.getPriority());
        System.out.println(thread2.getName()+ ": " + thread2.getPriority());
        System.out.println(thread3.getName()+ ": " + thread1.getPriority());

//        Thread.sleep(10000);
        System.out.println(mainThread.getName()+ ": " + mainThread.getPriority());


        System.out.println("================================================================================================");
    }
}


/**
 * ## cpu的调度策略
 *
 * - **时间片：**cpu正常情况下的调度策略。即CPU分配给各个程序的时间，每个线程被分配一个时间段，称作它的时间片，即该进程允许运行的时间，使各个程序从表面上看是同时进行的。如果在时间片结束时进程还在运行，则CPU将被剥夺并分配给另一个进程。如果进程在时间片结束前阻塞或结束，则CPU当即进行切换。而不会造成CPU资源浪费。在宏观上：我们可以同时打开多个应用程序，每个程序并行不悖，同时运行。但在微观上：由于只有一个CPU，一次只能处理程序要求的一部分，如何处理公平，一种方法就是引入时间片，每个程序轮流执行。
 * - **抢占式：**高优先级的线程抢占cpu。
 *
 *
 * - 同优先级线程组成先进先出队列（先到先服务），使用时间片策略。
 * - 堆高优先级，使用优先调度的抢占式策略。
 *
 *
 *
 * **线程的优先级等级**（一共有10挡）
 *
 * - MAX_PRIORITY：10
 * - MIN_PRIORITY：1
 * - NORM_PRIORITY：5 (默认优先级)
 *
 * **获取和设置当前线程的优先级**
 *
 * - `getPriority();` 获取
 * - `setPriority(int p);` 设置
 *
 * **说明：高优先级的线程要抢占低优先级线程cpu的执行权。
 * 但是只是从概率上讲，高优先级的线程高概率的情况下被执行。
 * 并不意味着只有高优先级的线程执行完成以后，
 * 低优先级的线程才执行。**
 *
 *
 *
 * 线程的生命周期:
 *  创建 : Thread thread = new Thead();
 *  就绪 : thread.start(); 但还未得到时间片执行 run()方法体中的代码时;
 *  运行 : thread.start(); 得到时间片执行 run()方法体中的代码时;
 *  阻塞 : thread.start(); 失去时间片, 停止执行 run()方法体中的代码时;
 *  死亡 : thread.start(); run() 方法体中的代码执行完毕;
 *
 * 创建 --> 就绪 --> 运行 --> 死亡
 *          ^        |
 *          |        |
 *          <- 阻塞 <-
 *
 * 1. 创建(新建)：当一个Thread类或其子类的对象被声明并创建时，新的线程对象处于新建状态。
 * 2. 就绪：处于新建状态的线程被start()后，将进入线程队列等待CPU时间片，此时它已具备了运行的条件，只是没分配到CPU资源。
 * 3. 运行：当就绪的线程被调度并获得CPU资源时，便进入运行状态，run()方法定义了线程的操作和功能。
 * 4. 阻塞：在某种特殊情况下，被认为挂起或执行输入输出操作时，让出CPU并临时中止自己的执行，进入阻塞状态。
 * 5. 死亡：线程完成了它的全部工作或线程被提前强制性的中止或出现异常倒置导致结束。
 */
